using System;
using System.Web;
using System.IO;
using Jalal.Library.Utility;
using Jalal.Library.Data;
using BCGC.DAL;
using System.Configuration;
using System.Collections.Generic;
using Jalal.Library.DataStructure;
using System.Data;
using System.Data.SqlTypes;

namespace BCGC.BLL.BusinessObject.Resource
{
    public class Trailer : ResourceBase
    {
        private int trailerId;
        public int TrailerId
        {
            get { return trailerId; }
        }

        private String fileUrl;
        public String FileUrl
        {
            get
            {
                return fileUrl;
            }
            set
            {
                fileUrl = value;
            }
        }

        private string thumbnailImageUrl;
        public string ThumbnailImageUrl
        {
            get { return thumbnailImageUrl; }
            set { thumbnailImageUrl = value; }
        }

        private string previewImageUrl;
        public string PreviewImageUrl
        {
            get { return previewImageUrl; }
            set { previewImageUrl = value; }
        }

        private int width;
        public int Width
        {
            get { return width; }
            set { width = value; }
        }

        private int height;
        public int Height
        {
            get { return height; }
            set { height = value; }
        }

        public Trailer()
        {
            this.trailerId = 0;
            this.fileUrl = string.Empty;
            this.createDateTime = SqlDateTime.MinValue.Value;
            this.description = string.Empty;
            this.relatedGame = null;
            this.title = string.Empty;
            this.isActive = false;
            this.totalView = 0;
            this.rating = 0;
            this.totalRatingVote = 0;
            this.thumbnailImageUrl = string.Empty;
            this.previewImageUrl = string.Empty;
            this.width = 0;
            this.height = 0;
        }

        public Trailer(DataRow dataRow, bool fullLoad)
        {
            if (dataRow != null)
            {
                if (dataRow.Table.Columns.Contains("TrailerId"))
                    this.trailerId = (int)CommonUtility.FilterNull(dataRow["TrailerId"], typeof(int));
                if (dataRow.Table.Columns.Contains("FileUrl"))
                    this.fileUrl = (string)CommonUtility.FilterNull(dataRow["FileUrl"], typeof(string));
                if (dataRow.Table.Columns.Contains("ThumbnailImageUrl"))
                    this.thumbnailImageUrl = (string)CommonUtility.FilterNull(dataRow["ThumbnailImageUrl"], typeof(string));
                if (dataRow.Table.Columns.Contains("PreviewImageUrl"))
                    this.previewImageUrl = (string)CommonUtility.FilterNull(dataRow["PreviewImageUrl"], typeof(string));
                if (dataRow.Table.Columns.Contains("CreateDateTime"))
                    this.createDateTime = (DateTime)CommonUtility.FilterNull(dataRow["CreateDateTime"], typeof(DateTime));
                if (dataRow.Table.Columns.Contains("Description"))
                    this.description = (string)CommonUtility.FilterNull(dataRow["Description"], typeof(string));
                if (dataRow.Table.Columns.Contains("Title"))
                    this.title = (string)CommonUtility.FilterNull(dataRow["Title"], typeof(string));
                if (dataRow.Table.Columns.Contains("IsActive"))
                    this.isActive = (bool)CommonUtility.FilterNull(dataRow["IsActive"], typeof(bool));
                if (dataRow.Table.Columns.Contains("TotalView"))
                    this.totalView = (int)CommonUtility.FilterNull(dataRow["TotalView"], typeof(int));
                if (dataRow.Table.Columns.Contains("Rating"))
                    this.rating = (int)CommonUtility.FilterNull(dataRow["Rating"], typeof(int));
                if (dataRow.Table.Columns.Contains("TotalRatingVote"))
                    this.totalRatingVote = (int)CommonUtility.FilterNull(dataRow["TotalRatingVote"], typeof(int));
                if (dataRow.Table.Columns.Contains("Width"))
                    this.width = (int)CommonUtility.FilterNull(dataRow["Width"], typeof(int));
                if (dataRow.Table.Columns.Contains("Height"))
                    this.height = (int)CommonUtility.FilterNull(dataRow["Height"], typeof(int));

                if (fullLoad)
                    this.relatedGame = new Game(dataRow);
                else
                    this.relatedGame = null;
            }
            else
            {
                this.trailerId = 0;
                this.fileUrl = string.Empty;
                this.createDateTime = SqlDateTime.MinValue.Value;
                this.description = string.Empty;
                this.relatedGame = null;
                this.title = string.Empty;
                this.isActive = false;
                this.totalView = 0;
                this.rating = 0;
                this.totalRatingVote = 0;
                this.thumbnailImageUrl = string.Empty;
                this.previewImageUrl = string.Empty;
                this.width = 0;
                this.height = 0;
            }
        }

        private static ReadWriteCustomCollection<Trailer> LoadFromDataTable(DataTable data)
        {
            ReadWriteCustomCollection<Trailer> result = new ReadWriteCustomCollection<Trailer>();

            if (data != null && data.Rows.Count > 0)
            {
                foreach (DataRow row in data.Rows)
                {
                    result.Add(new Trailer(row, true));
                }
            }
            return result;
        }

        public static string UploadTrailerFile(HttpPostedFile postedFile)
        {
            return FileAccessUtility.UploadFile(postedFile, ConfigurationSettings.AppSettings["FCKeditor:UserFilesPath"] 
                + "file/trailer/", FileAccessUtility.FileTypes.Zip);
        }

        public static bool Create(string title, int gameId, string description, 
            string fileUrl, string thumbnailImageUrl, string previewImageUrl, int width, int height, bool isActive)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);
            int id = ResourceData.CreateNewTrailer(title, gameId, description, fileUrl, thumbnailImageUrl, 
                previewImageUrl, width, height, isActive);
            DataFactory.GetDataMiner().CommitTransaction();

            return (id > 0);
        }

        public static void Delete(List<int> trailersToDelete)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);
            DataTable trailerFiles = ResourceData.GetTrailerFileLocationsForDelete(trailersToDelete);
            DataFactory.GetDataMiner().CommitTransaction();

            DataFactory.GetDataMiner().BeginTransaction(false);

            try
            {
                int deletedItemCount = ResourceData.DeleteTrailers(trailersToDelete);
                if (deletedItemCount == trailersToDelete.Count)
                    DataFactory.GetDataMiner().CommitTransaction();
                else
                    throw new Exception("Failed to delete all items");

                if (trailerFiles != null && trailerFiles.Rows.Count > 0)
                {
                    foreach (DataRow row in trailerFiles.Rows)
                    {
                        string fileUrl = Convert.ToString(row["FileUrl"]);
                        string thumbnailImage = Convert.ToString(row["ThumbnailImageUrl"]);
                        string previewImage = Convert.ToString(row["PreviewImageUrl"]);

                        if(!string.IsNullOrEmpty(fileUrl))
                            FileAccessUtility.DeleteFile(fileUrl);

                        if (!string.IsNullOrEmpty(thumbnailImage))
                            FileAccessUtility.DeleteFile(thumbnailImage);

                        if (!string.IsNullOrEmpty(previewImage))
                            FileAccessUtility.DeleteFile(previewImage);
                    }
                }
            }
            catch (Exception ex)
            {
                DataFactory.GetDataMiner().RollBackTransaction();
                throw ex;
            }
        }

        public static void UpdateActive(List<int> activeTrailers, List<int> inactiveTrailers)
        {
            DataFactory.GetDataMiner().BeginTransaction(false);

            try
            {
                int updatedItemCount = ResourceData.UpdateActiveTrailer(activeTrailers,
                    inactiveTrailers);
                if (updatedItemCount == activeTrailers.Count + inactiveTrailers.Count)
                    DataFactory.GetDataMiner().CommitTransaction();
                else
                    throw new Exception("Failed to update all items");
            }
            catch (Exception ex)
            {
                DataFactory.GetDataMiner().RollBackTransaction();
                throw ex;
            }
        }

        public static ReadWriteCustomCollection<Trailer> GetAllTrailers(int currentPageIndex,
            string sortOrder, int pageSize, string title, string gameTitle, DateTime? createDateFrom,
            DateTime? createDateTo, bool? isActive, out int totalData)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);

            totalData = 0;

            DataTable trailerData = ResourceData.GetAllTrailers(currentPageIndex, sortOrder, pageSize, 
                title, gameTitle, createDateFrom, createDateTo, isActive, out totalData);
            ReadWriteCustomCollection<Trailer> trailers = LoadFromDataTable(trailerData);

            DataFactory.GetDataMiner().CommitTransaction();

            return trailers;
        }

        public static Trailer GetTrailerById(int id)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);
            Trailer trailer = null;
            DataTable data = ResourceData.GetTrailerById(id);
            if (data != null && data.Rows.Count > 0)
                trailer = new Trailer(data.Rows[0], true);

            DataFactory.GetDataMiner().CommitTransaction();

            return trailer;
        }

        public static bool Update(int id, string title, int gameId, string description, 
            string fileUrl, string thumbnailImageUrl, string previewImageUrl, int width, int height, bool isActive)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);
            List<int> trailersToDelete = new List<int>();
            trailersToDelete.Add(id);
            DataTable trailerFiles = ResourceData.GetTrailerFileLocationsForDelete(trailersToDelete);
            DataFactory.GetDataMiner().CommitTransaction();

            if (trailerFiles != null && trailerFiles.Rows.Count > 0)
            {
                foreach (DataRow row in trailerFiles.Rows)
                {
                    string oldFileUrl = Convert.ToString(row["FileUrl"]);
                    string thumbnailImage = Convert.ToString(row["ThumbnailImageUrl"]);
                    string previewImage = Convert.ToString(row["PreviewImageUrl"]);

                    if (!string.IsNullOrEmpty(oldFileUrl) && fileUrl != oldFileUrl)
                        FileAccessUtility.DeleteFile(oldFileUrl);

                    if (!string.IsNullOrEmpty(thumbnailImage) && thumbnailImageUrl != thumbnailImage)
                        FileAccessUtility.DeleteFile(thumbnailImage);

                    if (!string.IsNullOrEmpty(previewImage) && previewImageUrl != previewImage)
                        FileAccessUtility.DeleteFile(previewImage);
                }
            }

            DataFactory.GetDataMiner().BeginTransaction(true);
            int updateCount = ResourceData.UpdateTrailer(id, title, gameId, description, fileUrl,
                thumbnailImageUrl, previewImageUrl, width, height, isActive);
            DataFactory.GetDataMiner().CommitTransaction();

            return (updateCount > 0);
        }

        public static ReadWriteCustomCollection<Trailer> GetAllTrailersByGame(int currentPageIndex, string sortOrder,
            int pageSize, int gameId, out int totalData)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);

            totalData = 0;

            DataTable trailerData = ResourceData.GetAllTrailersByGameId(currentPageIndex, sortOrder, pageSize,
                gameId, out totalData);
            ReadWriteCustomCollection<Trailer> trailers = LoadFromDataTable(trailerData);

            DataFactory.GetDataMiner().CommitTransaction();

            return trailers;
        }
    }
}
